package cn.edu.swu.mhans.game.service.impl;

import cn.edu.swu.mhans.common.player.NegotiationCommand;
import cn.edu.swu.mhans.common.util.UserWebSocketSessionUtil;
import cn.edu.swu.mhans.game.constants.GameQueueName;
import cn.edu.swu.mhans.game.constants.NormalCommandType;
import cn.edu.swu.mhans.game.service.GameService;
import cn.edu.swu.mhans.room.constant.RoomStatus;
import cn.edu.swu.mhans.room.service.RoomService;
import cn.edu.swu.mhans.room.share.base.BaseRoom;
import cn.edu.swu.mhans.user.service.UserService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.websocket.Session;
import java.io.IOException;
import java.util.Map;

/**
 * @author ZhanJingbo
 * @version 1.0.0
 * Created on 2017/11/11
 */
@Service
@Slf4j
public class GameServiceImpl implements GameService {


    @Autowired
    private UserService userService;

    @Autowired
    private RoomService roomService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    /**
     * 用户连入WebSocket房间所进行的操作
     *
     * @param roomId   房间Id
     * @param playerId 玩家Id
     * @param session  WebSocket的Session
     */
    @Override
    public void onConnectionOpen(String roomId, Long playerId, Session session) {
        log.info("用户:{},进入房间:{}", playerId, roomId);
        // 存储用户WebSocketSession
        String sessionKey = UserWebSocketSessionUtil.getUserWebSocketSessionKey(roomId, playerId);
        userService.saveUserWebSocketSession(sessionKey, session);

        NegotiationCommand intoRoomCommand = new NegotiationCommand(NormalCommandType.INTO_ROOM.getValue(), roomId);
        Map<String, Object> dataMap = Maps.newHashMap();
        dataMap.put("playerId", playerId);
        intoRoomCommand.setData(dataMap);
        sendNegotiationCommand(intoRoomCommand);
    }

    /**
     * 用户发送消息的处理接口
     *
     * @param jsonCommand 用户发送的消息，应该是Command对象的Json串
     */
    @Override
    public void onMessage(String jsonCommand) throws IOException {
        log.debug("消息接收：" + jsonCommand);
        ObjectMapper mapper = new ObjectMapper();
        NegotiationCommand negotiationCommand = mapper.readValue(jsonCommand, NegotiationCommand.class);
        sendNegotiationCommand(negotiationCommand);
    }

    /**
     * 用户断开连接所执行的操作
     *
     * @param roomId   房间id
     * @param playerId 玩家id
     */
    @Override
    public void onConnectionClose(String roomId, Long playerId) {
        log.info("用户:{},退出房间:{}", playerId, roomId);
        BaseRoom room = roomService.findOne(roomId);
        // 游戏异常退出
        if (null != room && room.getRoomStatus() != RoomStatus.READY.getValue()) {
            NegotiationCommand command = new NegotiationCommand(NormalCommandType.BREAK_OFF.getValue(), roomId);
            sendNegotiationCommand(command);
            roomService.delete(roomId);
        }

    }

    /**
     * 连接过程中的异常处理
     *
     * @param error 发生的异常
     */
    @Override
    public void onConnectionError(Throwable error) {
        log.error("游戏异常", error);
    }

    private void sendNegotiationCommand(NegotiationCommand command) {
        try {
            ObjectMapper mapper = new ObjectMapper();
            BaseRoom baseRoom = roomService.findOne(command.getRoomId());
            amqpTemplate.convertAndSend(GameQueueName.getQueueNameByRoomType(baseRoom.getRoomType()), mapper.writeValueAsString(command));
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

}
